package lex.fractal;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import lex.fractal.algorithm.Fractal;

/**
 * 1.Calculate the line segment's midpoint.<br>
 * 2.Move the midpoint up or down by a randomly selected distance.<br>
 * 3.At the midpoint, divide the line segment into two line segments. Repeat all
 * three steps for each line segment.
 */
public class MountainRidgelineFractal implements Fractal {
	private final static int MAX_DEPTH = 8;
	private Color violet = new Color(191, 64, 251);
	private int[] heights;

	public String getName() {
		return "Mountain ridgeline";
	}

	public void generate(Graphics2D g, int depth, int width, int height) {
		g.setPaint(new GradientPaint(0, 0, violet, 0, height, Color.yellow));
		g.fill(new Rectangle(0, 0, width, height));
		if (depth == MAX_DEPTH) {
			heights = new int[width];
			for (int i = 0; i < heights.length; i++)
				heights[i] = height / 2;
		}
		g.setColor(Color.black);
		mr(0, height / 2, width - 1, height / 2, depth, g);
		if (depth == MAX_DEPTH) {
			for (int i = 0; i < width; i++)
				g.drawLine(i, heights[i], i, height - 1);
			heights = null;
		}
	}

	public int getMaximalDepth() {
		return MAX_DEPTH;
	}

	private void mr(int x1, int y1, int x2, int y2, int depth, Graphics2D g) {
		if (depth <= 0 || x1 == x2) {
			g.drawLine(x1, y1, x2, y2);
			return;
		}
		int midx = (x1 + x2) / 2;
		int midy = (y1 + y2) / 2;
		// int len = (int) Math.sqrt( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 -
		// y1) );
		if (rnd(2) == 0)
			midy -= rnd(x2 - x1) / 3;
		else
			midy += rnd(x2 - x1) / 3;
		if (heights != null)
			heights[midx] = midy;
		mr(x1, y1, midx, midy, depth - 1, g);
		mr(midx, midy, x2, y2, depth - 1, g);
	}

	private int rnd(int limit) {
		return (int) (Math.random() * limit);
	}
}
